package cn.maydaymemory.mastery.command.api;

import cn.maydaymemory.mastery.annotation.CommandHandler;
import cn.maydaymemory.mastery.message.util.EdgingUtil;
import cn.maydaymemory.mastery.message.util.NeatText;
import cn.maydaymemory.mastery.message.util.PageMessage;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.Configuration;
import org.bukkit.entity.Player;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;

public abstract class CommandStructure {
    protected CommandSender sender;
    protected Player player;
    protected String label;
    protected String[] args;
    private Map<CommandStructure,CommandStructureExecutor> childExecutors = new HashMap<>();
    private Map<String,CommandStructure> childStructures = new HashMap<>();

    private String description_path = "descriptions";
    private PageMessage helper=new PageMessage(new ArrayList<>());
    private List<String> complete = new ArrayList<>();

    private boolean titled=false;
    void redefine(CommandSender sender, String label, String[] args, Method method) throws InvocationTargetException, IllegalAccessException {
        this.sender=sender;
        if(sender instanceof Player) player = (Player) sender;
        else player=null;
        this.label=label;
        this.args=args;
        access();
        if(method!=null) method.invoke(this);
    }
    public CommandStructureExecutor getChildStructureExecutor(CommandStructure child){
        return childExecutors.get(child);
    }

    public CommandStructure getChildStructure(String name){
        return childStructures.get(name);
    }

    void initHelper(Configuration language){
        NeatText neatHelperText= new NeatText();
        neatHelperText.width(60);
        List<String> list = new ArrayList<>();
        for(Method method:this.getClass().getDeclaredMethods()) {
            method.setAccessible(true);
            CommandHandler handler = method.getDeclaredAnnotation(CommandHandler.class);
            if (handler != null) {
                if(!handler.visable()) continue;
                StringBuilder pars=new StringBuilder();
                for(String par:handler.parameters()){
                    pars.append(par);
                    pars.append("  ");
                }
                String description = language.getString(description_path+"."+handler.name(),"No description.");
                String font = "§f"+handler.name()+"  "+pars.toString()+" → §7"+description;
                list.add(font);

                if(!complete.contains(handler.name())) complete.add(handler.name());
            }
        }
        for(String name: childStructures.keySet()){
            String description = language.getString(description_path+"."+name,"No description.");
            String font = "§f"+name+" → §7"+description;
            list.add(font);

            if(!complete.contains(name)) complete.add(name);
        }
        list.sort(new SpellComparator());
        for(String str : list){
            neatHelperText.addText(str,true);
        }
        this.helper.messages(neatHelperText.getTexts()).stepLength(6);
    }

    protected PageMessage helper(){ return helper; }

    protected void sendHelp(int page){
        if(sender==null) return;
        sender.sendMessage(" ");
        helper.viewer(sender).sendMessages(page);
    }

    public void registerChildStructure(String name ,CommandStructure structure, Configuration language){
        childStructures.put(name,structure);
        initHelper(language);
        CommandStructureExecutor executor = new CommandStructureExecutor(structure,language);
        structure.changeHelperTitle("§7"+name+"'s help");
        childExecutors.put(structure,executor);
    }

    public void setDescription(String _description_path, Configuration language){
        description_path = _description_path;
        initHelper(language);
    }

    public void changeHelperTitle(String title) {
        helper.title(EdgingUtil.getHeader(title, 60));
        titled=true;
    }

    public boolean isTitled(){return titled;}

    List<String> complete(){ return new ArrayList<>(complete); }

    protected abstract void access();

    class SpellComparator implements Comparator<String> {
        public int compare(String o1, String o2) {
            try {
                // 取得比较对象的汉字编码，并将其转换成字符串
                String s1 = new String(o1.getBytes("GB2312"), StandardCharsets.ISO_8859_1);
                String s2 = new String(o2.getBytes("GB2312"), StandardCharsets.ISO_8859_1);
                // 运用String类的 compareTo（）方法对两对象进行比较
                return s1.compareTo(s2);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
    }
}
